using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.IO;
using System.Xml;

namespace Woz
{
    /// <summary>
    /// the screen class represents a woz screen
    /// </summary>
    public class Screen
    {
        /// <summary>
        /// private constructor that does nothing
        /// </summary>
        private Screen()
        {
            // set the ID
            this.mID = ++sAutoID;
        }

        /// <summary>
        /// default screen constructor
        /// </summary>
        /// <param name="pName">the name of the screen</param>
        internal Screen(string pName, bool pHidden)
        {
            // set the ID
            this.mID = ++sAutoID;

            // set the name of this screen
            this.mName = pName;

            // set the screen to not be hidden
            this.mHidden = pHidden;

            // initialize the list of next screens
            this.mNextScreens = new List<Woz.Screen>();

            // initialize the thumbnail image
            this.mThumbnailImage = new Bitmap(600, 400, PixelFormat.Format32bppRgb);

            // create the screen thumbnail for the thumbnail slider
            this.mSliderThumbnail = new Woz.ScreenThumbnail(this);

            // create the screen thumbnail for the edit transitions mode
            this.mTransitionsThumbnail = new Woz.ScreenThumbnail(this);
        }

        /// <summary>
        /// gets the unique ID of this screen
        /// </summary>
        public uint ID
        {
            get
            {
                return this.mID;
            }
            //internal set
            //{
            //    // set the ID
            //    this.mID = value;

            //    // update the auto id
            //    sAutoID = Math.Max(sAutoID, value + 1);
            //}
        }

        /// <summary>
        /// gets the name of this screen
        /// </summary>
        public string Name
        {
            get
            {
                return this.mName;
            }
            internal set
            {
                this.mName = value;
            }
        }

        /// <summary>
        /// gets the thumbnail image associated with this screen
        /// </summary>
        public Image Thumbnail
        {
            get
            {
                return this.mThumbnailImage;
            }
        }

        /// <summary>
        /// gets the thumbnail control associated with the screen slider
        /// </summary>
        public Woz.ScreenThumbnail SliderThumbnail
        {
            get
            {
                return this.mSliderThumbnail;
            }
        }

        /// <summary>
        /// gets the thumbnail control associated with the edit screen transitions mode
        /// </summary>
        public Woz.ScreenThumbnail TransitionsThumbnail
        {
            get
            {
                return this.mTransitionsThumbnail;
            }
        }

        /// <summary>
        /// gets or whether the screen is hidden or not
        /// </summary>
        public bool Hidden
        {
            get
            {
                return this.mHidden;
            }
            set
            {
                this.mHidden = true;
            }
        }

        /// <summary>
        /// gets the next screens
        /// </summary>
        public Woz.Screen[] NextScreens
        {
            get
            {
                return this.mNextScreens.ToArray();
            }
        }

        /// <summary>
        /// gets the bounding box of the selected entities
        /// </summary>
        public Rectangle SelectedEntitiesBoundingBox
        {
            get
            {
                return this.mSelectedEntitiesBoundingBox;
            }
        }

        /// <summary>
        /// add a screen to the next screens
        /// </summary>
        /// <param name="pScreen">the new screen to add to the next screens</param>
        internal void AddNextScreen(Woz.Screen pScreen)
        {
            if (!this.mNextScreens.Contains(pScreen))
            {
                if (!pScreen.Hidden)
                {
                    this.mNextScreens.Add(pScreen);
                }
            }
        }

        /// <summary>
        /// removes a screen from the next screens
        /// </summary>
        /// <param name="pScreen">the new screen to add to the next screens</param>
        internal void RemoveNextScreen(Woz.Screen pScreen)
        {
            this.mNextScreens.Remove(pScreen);
        }

        /// <summary>
        /// clone this screen and return a reference to the clone
        /// </summary>
        /// <param name="pName">the name to give the clone</param>
        public Woz.Screen Clone(string pName)
        {
            // create the new screen using the empty private constructor
            Woz.Screen screen = new Woz.Screen();

            // set the name of this screen
            screen.mName = pName;

            // set whether the screen is hidden
            screen.mHidden = this.mHidden;

            // create the list of next screens
            screen.mNextScreens = new List<Woz.Screen>();

            // clone the next screens
            foreach (Woz.Screen nextScreen in this.mNextScreens)
            {
                screen.mNextScreens.Add(nextScreen);
            }

            // clone the thumbnail image
            Rectangle thumbRect = new Rectangle(0, 0, this.mThumbnailImage.Width, this.mThumbnailImage.Height);
            screen.mThumbnailImage = this.mThumbnailImage.Clone(thumbRect, PixelFormat.Format32bppRgb) as Bitmap;

            // clone the screen thumbnails
            screen.mSliderThumbnail = new Woz.ScreenThumbnail(screen);

            // clone the transition thumbnail
            screen.mTransitionsThumbnail = new Woz.ScreenThumbnail(screen);

            // return it
            return screen;
        }

        
        /// <summary>
        /// the next screens in the sequence
        /// </summary>
        private List<Woz.Screen> mNextScreens;

        /// <summary>
        /// the bounding box of the selected entities
        /// </summary>
        private Rectangle mSelectedEntitiesBoundingBox;

        /// <summary>
        /// save the screen thumbnail image
        /// </summary>
        private Bitmap mThumbnailImage;

        /// <summary>
        /// the screen thumbnail object for the screen slider associated with this screen
        /// </summary>
        private Woz.ScreenThumbnail mSliderThumbnail;

        /// <summary>
        /// the screen thumbnail object for the edit screen transitions associated with this screen
        /// </summary>
        private Woz.ScreenThumbnail mTransitionsThumbnail;

        /// <summary>
        /// whether this screen is hidden or not
        /// </summary>
        private bool mHidden;

        /// <summary>
        /// the name of this screen
        /// </summary>
        private string mName;

        /// <summary>
        /// the unique of the screen
        /// </summary>
        private uint mID;

        /// <summary>
        /// the auto generated id
        /// </summary>
        private static uint sAutoID;
    }
}
